\chapter{循环}

\section{while}

\subsection{while}

while循环会对条件进行判断，如果条件成立，就会执行循环体，然后再次判断条件，直到条件不成立。\\

while循环的次数由循环变量的变化决定，因此while循环一般都包括对循环变量的初值、判断和更新。

\vspace{-0.5cm}

\begin{lstlisting}[language=Python]
i = 1			# initial value
while i <= 5:	# condition
	print("In loop: i =", i)
	i += 1		# update
print("After loop: i =", i)
\end{lstlisting}

while循环的特点是先判断、再执行，因此循环体有可能会执行一次或多次，也有可能一次也不会执行。\\

\mybox{平均身高}

\begin{lstlisting}[language=Python]
NUM_PEOPLE = 5

total = 0

i = 1
while i <= NUM_PEOPLE:
	height = float(input("Enter person %d's height: " % i))
	total += height
	i += 1

average = total / NUM_PEOPLE
print("Average height: %.2f" % average)
\end{lstlisting}

\begin{tcolorbox}
	\mybox{运行结果}
	\begin{verbatim}
Enter person 1's height: 160.8
Enter person 2's height: 175.2
Enter person 3's height: 171.2
Enter person 4's height: 181.3
Enter person 5's height: 164
Average height: 170.50
\end{verbatim}
\end{tcolorbox}

\vspace{0.5cm}

\mybox{整数位数}

\begin{lstlisting}[language=Python]
num = int(input("Enter an integer: "))
n = 0

while num != 0:
	num //= 10
	n += 1

print("Digits:", n)
\end{lstlisting}

\begin{tcolorbox}
	\mybox{运行结果}
	\begin{verbatim}
Enter an integer: 123
Digits: 3
\end{verbatim}
\end{tcolorbox}

\vspace{0.5cm}

\mybox{猜数字}

\begin{lstlisting}[language=Python]
import random

answer = random.randint(1, 100)
cnt = 0

while True:
	num = int(input("Guess a number: "))
	cnt += 1

	if num > answer:
		print("Too high")
	elif num < answer:
		print("Too low")
	else:
		break

print("Correct! You guessed %d times." % cnt)
\end{lstlisting}

\begin{tcolorbox}
	\mybox{运行结果}
	\begin{verbatim}
Guess a number: 50
Too high
Guess a number: 25
Too low
Guess a number: 37
Too low
Guess a number: 43
Too high
Guess a number: 40
Too high
Guess a number: 38
Too low
Guess a number: 39
Correct! You guessed 7 times.
\end{verbatim}
\end{tcolorbox}

\newpage

\section{for}

\subsection{for}

while循环将循环变量的初值、条件和更新写在了三个地方，但是这样不容易明显地看出循环变量的变化。\\

for循环在一行内就可以清晰地表示出循环的次数，因此对于指定次数的循环一般更多地会采用for循环，而对于不确定次数的一般会采用while循环。\\

range()函数能够生成指定范围的整数序列：

\vspace{-0.5cm}

\begin{lstlisting}[language=Python]
for i in range(5):
    print(i, end=' ')		# 0 1 2 3 4

for i in range(10, 15):
	print(i, end=' ')		# 10 11 12 13 14

for i in range(1, 10, 2):
	print(i, end=' ')		# 1 3 5 7 9
\end{lstlisting}

\vspace{0.5cm}

\mybox{累加}

\begin{lstlisting}[language=Python]
sum = 0
for i in range(1, 101):
	sum += i
print("Sum =", sum)
\end{lstlisting}

\begin{tcolorbox}
	\mybox{运行结果}
	\begin{verbatim}
Sum = 5050
\end{verbatim}
\end{tcolorbox}

\vspace{0.5cm}

\mybox{斐波那契数列}

\begin{figure}[H]
	\centering
	\includegraphics[scale=0.5]{img/Chapter3/3-2/1.png}
\end{figure}

\begin{lstlisting}[language=Python]
n = int(input("Enter the number of terms: "))

if n == 1:
	print(1)
elif n == 2:
	print(1, 1)
else:
	num1 = 1
	num2 = 1
	print(1, 1, end=' ')
	for i in range(3, n + 1):
		val = num1 + num2
		print(val, end=' ')
		num1 = num2
		num2 = val
	print()
\end{lstlisting}

\begin{tcolorbox}
	\mybox{运行结果}
	\begin{verbatim}
Enter the number of terms: 10
1 1 2 3 5 8 13 21 34 55
\end{verbatim}
\end{tcolorbox}

\vspace{0.5cm}

\subsection{嵌套循环}

循环也可以嵌套使用，外层循环每执行一次，内层循环就会执行多次。

\vspace{-0.5cm}

\begin{lstlisting}[language=Python]
for i in range(2):
	for j in range(3):
		print("i = %d, j = %d" % (i, j))
\end{lstlisting}

\begin{tcolorbox}
	\mybox{运行结果}
	\begin{verbatim}
i = 0, j = 0
i = 0, j = 1
i = 0, j = 2
i = 1, j = 0
i = 1, j = 1
i = 1, j = 2
\end{verbatim}
\end{tcolorbox}

\vspace{0.5cm}

\mybox{九九乘法表}\\

\begin{table}[H]
	\centering
	\setlength{\tabcolsep}{1.5mm}{
		\begin{tabular}{|c|c|c|c|c|c|c|c|c|}
			\hline
			1*1=1 & 1*2=2  & 1*3=3  & 1*4=4  & 1*5=5  & 1*6=6  & 1*7=7  & 1*8=8  & 1*9=9  \\
			\hline
			2*1=2 & 2*2=4  & 2*3=6  & 2*4=8  & 2*5=10 & 2*6=12 & 2*7=14 & 2*8=16 & 2*9=18 \\
			\hline
			3*1=3 & 3*2=6  & 3*3=9  & 3*4=12 & 3*5=15 & 3*6=18 & 3*7=21 & 3*8=24 & 3*9=27 \\
			\hline
			4*1=4 & 4*2=8  & 4*3=12 & 4*4=16 & 4*5=20 & 4*6=24 & 4*7=28 & 4*8=32 & 4*9=36 \\
			\hline
			5*1=5 & 5*2=10 & 5*3=15 & 5*4=20 & 5*5=25 & 5*6=30 & 5*7=35 & 5*8=40 & 5*9=45 \\
			\hline
			6*1=6 & 6*2=12 & 6*3=18 & 6*4=24 & 6*5=30 & 6*6=36 & 6*7=42 & 6*8=48 & 6*9=54 \\
			\hline
			7*1=7 & 7*2=14 & 7*3=21 & 7*4=28 & 7*5=35 & 7*6=42 & 7*7=49 & 7*8=56 & 7*9=63 \\
			\hline
			8*1=8 & 8*2=16 & 8*3=24 & 8*4=32 & 8*5=40 & 8*6=48 & 8*7=56 & 8*8=64 & 8*9=72 \\
			\hline
			9*1=9 & 9*2=18 & 9*3=27 & 9*4=36 & 9*5=45 & 9*6=54 & 9*7=63 & 9*8=72 & 9*9=81 \\
			\hline
		\end{tabular}
	}
\end{table}

\begin{lstlisting}[language=Python]
for i in range(1, 10):
    for j in range(1, 10):
        print("%d*%d=%d\t" % (i, j, i * j), end='')
    print()
\end{lstlisting}

\vspace{0.5cm}

\mybox{打印图案}

\begin{lstlisting}
*
**
***
****
*****
\end{lstlisting}

\begin{lstlisting}[language=Python]
for i in range(1, 6):
	for j in range(1, i + 1):
		print("*", end='')
	print()
\end{lstlisting}

\newpage

\section{break or continue?}

\subsection{break}

break可用于跳出当前的switch或循环结构。在一些情况下，在循环的中途已经完成了某个目标，没有必要再进行剩余的循环，这时就可以使用break跳出循环。\\

例如在判断一个数$ n $是否为素数时，利用循环逐个判断$ 2 \sim n - 1 $之间的数是否能整除$ n $。只要发现其中有一个数能整除$ n $，就证明$ n $不是素数，可以跳出循环，不必再进行剩余的检查。\\

\mybox{素数}

\begin{lstlisting}[language=Python]
import math

n = int(input("Enter an integer: "))

is_prime = True
for i in range(2, int(math.sqrt(n)) + 1):
	if n % i == 0:
		is_prime = False
		break

if is_prime:
	print(n, "is a prime number")
else:
	print(n, "is not a prime number")
\end{lstlisting}

\begin{tcolorbox}
	\mybox{运行结果}
	\begin{verbatim}
Enter an integer: 17
17 is a prime number
\end{verbatim}
\end{tcolorbox}

\vspace{0.5cm}

\subsection{continue}

continue与break使用方法类似，但是它并不是跳出循环，而是跳过本轮循环，直接开始下一轮循环。\\

\mybox{正数平方和}

\begin{lstlisting}[language=Python]
n = 10
print("Enter %d integers: " % n)

sum_square = 0
for i in range(n):
	num = int(input())
	if num < 0:
		continue
	sum_square += num * num

print("Sum of squares of positive integers:", sum_square)
\end{lstlisting}

\begin{tcolorbox}
	\mybox{运行结果}
	\begin{verbatim}
Enter 10 integers: 
5 
7
-2
0
4
-4
-9
3
9
5
Sum of squares of positive integers: 205
\end{verbatim}
\end{tcolorbox}

\newpage